﻿using System;
using Asplode.Events;
using BEPUphysics.Entities;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Asplode
{
    public class InputManager
    {
        private Game game;

        public InputManager(Game game)
        {
            this.game = game;
        }

        public void Update(GameTime gameTime)
        {
            // Get input.
            KeyboardState kstate = Keyboard.GetState();
            MouseState mState = Mouse.GetState();

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed
                || kstate.IsKeyDown(Keys.Escape)
                )
                game.Exit();

            // Adjust the camera.
            {
                if (kstate.IsKeyDown(Keys.OemOpenBrackets))
                {
                    game.camRotation += MathHelper.ToRadians(1);
                }

                if (kstate.IsKeyDown(Keys.OemCloseBrackets))
                {
                    game.camRotation -= MathHelper.ToRadians(1);
                }

                if (kstate.IsKeyDown(Keys.Subtract)
                    || kstate.IsKeyDown(Keys.OemMinus))
                {
                    game.Map.CameraPosition = game.Map.CameraPosition + new Vector3(0, 10, 0);
                }

                if (kstate.IsKeyDown(Keys.Add)
                    || kstate.IsKeyDown(Keys.OemPlus))
                {
                    game.Map.CameraPosition = new Vector3(game.Map.CameraPosition.X, Math.Max(game.Map.CameraPosition.Y - 10, 1), game.Map.CameraPosition.Z);
                }
            }

            if (kstate.IsKeyDown(Keys.Z))
            {
                Random random = new Random();
                float numZombies = 10;
                float x = (float)(random.NextDouble() - 0.5) * numZombies * 10;
                float z = (float)(random.NextDouble() - 0.5) * numZombies * 10;
                Vector3 position = new Vector3(x, 0, z);
                //gameObjectFactory.AddZombie(position);

                float radius = 1;
                float diameter = radius * 2;
                Cylinder cylinder = new Cylinder(position + new Vector3(0, radius, 0), radius * 2, radius, (float)Math.Pow(radius, 3));

                ZombieSpawnEvent zombieSpawn = new ZombieSpawnEvent(cylinder);
                game.EventDispatcher.Handle(zombieSpawn);
            }



            // Adjust the local player's state based on input.

            //Character player = game.player;

            //player.isShooting = (ButtonState.Pressed == mState.LeftButton);

            // Rotate the player instantaneously.
            {
                int torqueDirection = (kstate.IsKeyDown(Keys.A) ? 1 : 0)
                                    + (kstate.IsKeyDown(Keys.D) ? -1 : 0);

                // Update the player's rotation whether they asked for it or
                // not. This is to negate the effects of any rotation caused by
                // collisions.
              //  player.rotation += (float)(torqueDirection * 5 * gameTime.ElapsedGameTime.TotalSeconds);

                // This will cause odd collision behavior if the player's body
                // is not round with respect to the Y-axis. Cylinders and
                // spheres are fine.
               // player.gameObject.body.orientationMatrix = Matrix.CreateRotationY((float)player.rotation);
            }

            // Move the player gradually.
            {
                int accelerationDirection = (kstate.IsKeyDown(Keys.W) ? 1 : 0)
                                          + (kstate.IsKeyDown(Keys.S) ? -1 : 0);

                if (accelerationDirection != 0)
                {
                    float acceleration = (float)(accelerationDirection * 20 * gameTime.ElapsedGameTime.TotalSeconds);

                   // Vector3 impulse = new Vector3((float)Math.Cos(player.rotation), 0.0f, (float)-Math.Sin(player.rotation));
                   // impulse *= acceleration * player.gameObject.body.mass;
                  //  player.gameObject.body.applyLinearImpulse(ref impulse);
                }
            }
        }
    }
}
